bitkeeper revision 1.697 (401a7dcfLSasqkAaMngsKdiVm_puVw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 30 Jan 2004 15:52:47 +0000 (15:52 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 30 Jan 2004 15:52:47 +0000 (15:52 +0000)
config.h, ide-cd.c, dom0_ops.c, pci-pc.c:
  Fix stack overflows in Xen.

xen/arch/i386/pci-pc.c
xen/common/dom0_ops.c
xen/drivers/ide/ide-cd.c
xen/include/xeno/config.h

index d63a54a79c1af54f16f0bb64e5d99e8897b1f917..bb5ba8d2990a36f645d6f96c998faf83dae35a6e 100644 (file)
@@ -442,21 +442,36 @@ static struct pci_ops pci_direct_conf2 = {
 static int __devinit pci_sanity_check(struct pci_ops *o)
 {
        u16 x;
-       struct pci_bus bus;             /* Fake bus and device */
-       struct pci_dev dev;
+       struct pci_bus *bus;            /* Fake bus and device */
+       struct pci_dev *dev;
+       int ret = 0;
 
        if (pci_probe & PCI_NO_CHECKS)
                return 1;
-       bus.number = 0;
-       dev.bus = &bus;
-       for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++)
-               if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) &&
+
+       bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+       dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+       if ( (bus == NULL) || (dev == NULL) )
+               goto out;
+
+       bus->number = 0;
+       dev->bus = bus;
+       for(dev->devfn=0; dev->devfn < 0x100; dev->devfn++)
+               if ((!o->read_word(dev, PCI_CLASS_DEVICE, &x) &&
                     (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
-                   (!o->read_word(&dev, PCI_VENDOR_ID, &x) &&
+                   (!o->read_word(dev, PCI_VENDOR_ID, &x) &&
                     (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
-                       return 1;
+               {
+                       ret = 1;
+                       break;
+               }
+ out:
+       if ( bus != NULL )
+               kfree(bus);
+       if ( dev != NULL)
+               kfree(dev);
        DBG("PCI: Sanity check failed\n");
-       return 0;
+       return ret;
 }
 
 static struct pci_ops * __devinit pci_check_direct(void)
index d1a2983ea66bd4899689c39667e7149a6c59e9e9..b3aa93ca3b78ef3442bcee5b91a45e959581a4b6 100644 (file)
@@ -59,27 +59,36 @@ static void read_msr_for(void *unused)
 long do_dom0_op(dom0_op_t *u_dom0_op)
 {
     long ret = 0;
-    dom0_op_t op;
+    dom0_op_t *op;
 
     if ( !IS_PRIV(current) )
         return -EPERM;
 
-    if ( copy_from_user(&op, u_dom0_op, sizeof(op)) )
-        return -EFAULT;
+    if ( (op = kmalloc(sizeof(*op), GFP_KERNEL)) == NULL )
+        return -ENOMEM;
 
-    if ( op.interface_version != DOM0_INTERFACE_VERSION )
-        return -EACCES;
+    if ( copy_from_user(op, u_dom0_op, sizeof(*op)) )
+    {
+        ret = -EFAULT;
+        goto out;
+    }
+
+    if ( op->interface_version != DOM0_INTERFACE_VERSION )
+    {
+        ret = -EACCES;
+        goto out;
+    }
 
-    switch ( op.cmd )
+    switch ( op->cmd )
     {
 
     case DOM0_BUILDDOMAIN:
     {
-        struct task_struct * p = find_domain_by_id(op.u.builddomain.domain);
+        struct task_struct * p = find_domain_by_id(op->u.builddomain.domain);
         ret = -EINVAL;
         if ( p != NULL )
         {
-            ret = final_setup_guestos(p, &op.u.builddomain);
+            ret = final_setup_guestos(p, &op->u.builddomain);
             put_task_struct(p);
         }
     }
@@ -87,7 +96,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     case DOM0_STARTDOMAIN:
     {
-        struct task_struct * p = find_domain_by_id(op.u.startdomain.domain);
+        struct task_struct * p = find_domain_by_id(op->u.startdomain.domain);
         ret = -EINVAL;
         if ( p != NULL )
         {
@@ -104,7 +113,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     case DOM0_STOPDOMAIN:
     {
-        ret = stop_other_domain(op.u.stopdomain.domain);
+        ret = stop_other_domain(op->u.stopdomain.domain);
     }
     break;
 
@@ -125,13 +134,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         if ( p == NULL ) 
             goto exit_create;
 
-       if ( op.u.createdomain.name[0] )
+       if ( op->u.createdomain.name[0] )
         {
-            strncpy (p->name, op.u.createdomain.name, MAX_DOMAIN_NAME);
+            strncpy (p->name, op->u.createdomain.name, MAX_DOMAIN_NAME);
             p->name[MAX_DOMAIN_NAME - 1] = 0;
        }
 
-        ret = alloc_new_dom_mem(p, op.u.createdomain.memory_kb);
+        ret = alloc_new_dom_mem(p, op->u.createdomain.memory_kb);
         if ( ret != 0 ) 
         {
             __kill_domain(p);
@@ -140,8 +149,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
         ret = p->domain;
         
-        op.u.createdomain.domain = ret;
-        copy_to_user(u_dom0_op, &op, sizeof(op));
+        op->u.createdomain.domain = ret;
+        copy_to_user(u_dom0_op, op, sizeof(*op));
  
     exit_create:
         spin_unlock_irq(&create_dom_lock);
@@ -150,16 +159,16 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     case DOM0_DESTROYDOMAIN:
     {
-        unsigned int dom = op.u.destroydomain.domain;
-        int force = op.u.destroydomain.force;
+        unsigned int dom = op->u.destroydomain.domain;
+        int force = op->u.destroydomain.force;
         ret = (dom == IDLE_DOMAIN_ID) ? -EPERM : kill_other_domain(dom, force);
     }
     break;
 
     case DOM0_PINCPUDOMAIN:
     {
-        struct task_struct * p = find_domain_by_id(op.u.pincpudomain.domain);
-       int cpu = op.u.pincpudomain.cpu;
+        struct task_struct * p = find_domain_by_id(op->u.pincpudomain.domain);
+       int cpu = op->u.pincpudomain.cpu;
         ret = -EINVAL;
         if ( p != NULL )
         {
@@ -197,18 +206,18 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     case DOM0_BVTCTL:
     {
-        unsigned long  ctx_allow = op.u.bvtctl.ctx_allow;
+        unsigned long  ctx_allow = op->u.bvtctl.ctx_allow;
         ret = sched_bvtctl(ctx_allow);        
     }
     break;
 
     case DOM0_ADJUSTDOM:
     {
-        unsigned int   dom     = op.u.adjustdom.domain;
-        unsigned long  mcu_adv = op.u.adjustdom.mcu_adv;
-        unsigned long  warp    = op.u.adjustdom.warp;
-        unsigned long  warpl   = op.u.adjustdom.warpl;
-        unsigned long  warpu   = op.u.adjustdom.warpu;
+        unsigned int   dom     = op->u.adjustdom.domain;
+        unsigned long  mcu_adv = op->u.adjustdom.mcu_adv;
+        unsigned long  warp    = op->u.adjustdom.warp;
+        unsigned long  warpl   = op->u.adjustdom.warpl;
+        unsigned long  warpu   = op->u.adjustdom.warpu;
 
         ret = -EPERM;
         if ( dom != IDLE_DOMAIN_ID )
@@ -219,10 +228,10 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     case DOM0_GETMEMLIST:
     {
         int i;
-        struct task_struct *p = find_domain_by_id(op.u.getmemlist.domain);
-        unsigned long max_pfns = op.u.getmemlist.max_pfns;
+        struct task_struct *p = find_domain_by_id(op->u.getmemlist.domain);
+        unsigned long max_pfns = op->u.getmemlist.max_pfns;
         unsigned long pfn;
-        unsigned long *buffer = op.u.getmemlist.buffer;
+        unsigned long *buffer = op->u.getmemlist.buffer;
         struct list_head *list_ent;
 
         ret = -EINVAL;
@@ -246,8 +255,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
             }
             spin_unlock(&p->page_list_lock);
 
-            op.u.getmemlist.num_pfns = i;
-            copy_to_user(u_dom0_op, &op, sizeof(op));
+            op->u.getmemlist.num_pfns = i;
+            copy_to_user(u_dom0_op, op, sizeof(*op));
             
             put_task_struct(p);
         }
@@ -263,7 +272,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         read_lock_irqsave (&tasklist_lock, flags);
 
         while ( (p = p->next_task) != &idle0_task )
-            if ( !is_idle_task(p) && (p->domain >= op.u.getdomaininfo.domain) )
+            if ( !is_idle_task(p) && 
+                 (p->domain >= op->u.getdomaininfo.domain) )
                 break;
 
         if ( p == &idle0_task )
@@ -272,76 +282,78 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         }
         else
         {
-            op.u.getdomaininfo.domain      = p->domain;
-            strcpy (op.u.getdomaininfo.name, p->name);
-            op.u.getdomaininfo.processor   = p->processor;
-            op.u.getdomaininfo.has_cpu     = p->has_cpu;
-            op.u.getdomaininfo.state       = DOMSTATE_ACTIVE;
+            op->u.getdomaininfo.domain      = p->domain;
+            strcpy (op->u.getdomaininfo.name, p->name);
+            op->u.getdomaininfo.processor   = p->processor;
+            op->u.getdomaininfo.has_cpu     = p->has_cpu;
+            op->u.getdomaininfo.state       = DOMSTATE_ACTIVE;
             if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) )
-                op.u.getdomaininfo.state = DOMSTATE_STOPPED;
-            op.u.getdomaininfo.hyp_events  = p->hyp_events;
-            op.u.getdomaininfo.mcu_advance = p->mcu_advance;
-            op.u.getdomaininfo.tot_pages   = p->tot_pages;
-            op.u.getdomaininfo.cpu_time    = p->cpu_time;
-            op.u.getdomaininfo.shared_info_frame = 
+                op->u.getdomaininfo.state = DOMSTATE_STOPPED;
+            op->u.getdomaininfo.hyp_events  = p->hyp_events;
+            op->u.getdomaininfo.mcu_advance = p->mcu_advance;
+            op->u.getdomaininfo.tot_pages   = p->tot_pages;
+            op->u.getdomaininfo.cpu_time    = p->cpu_time;
+            op->u.getdomaininfo.shared_info_frame = 
                 __pa(p->shared_info) >> PAGE_SHIFT;
             if ( p->state == TASK_STOPPED )
             {
                 rmb(); /* Ensure that we see saved register state. */
-                op.u.getdomaininfo.ctxt.flags = 0;
-                memcpy(&op.u.getdomaininfo.ctxt.i386_ctxt, 
+                op->u.getdomaininfo.ctxt.flags = 0;
+                memcpy(&op->u.getdomaininfo.ctxt.i386_ctxt, 
                        &p->shared_info->execution_context,
                        sizeof(p->shared_info->execution_context));
                 if ( p->flags & PF_DONEFPUINIT )
-                    op.u.getdomaininfo.ctxt.flags |= ECF_I387_VALID;
-                memcpy(&op.u.getdomaininfo.ctxt.i387_ctxt,
+                    op->u.getdomaininfo.ctxt.flags |= ECF_I387_VALID;
+                memcpy(&op->u.getdomaininfo.ctxt.i387_ctxt,
                        &p->thread.i387,
                        sizeof(p->thread.i387));
-                memcpy(&op.u.getdomaininfo.ctxt.trap_ctxt,
+                memcpy(&op->u.getdomaininfo.ctxt.trap_ctxt,
                        p->thread.traps,
                        sizeof(p->thread.traps));
                 if ( (p->thread.fast_trap_desc.a == 0) &&
                      (p->thread.fast_trap_desc.b == 0) )
-                    op.u.getdomaininfo.ctxt.fast_trap_idx = 0;
+                    op->u.getdomaininfo.ctxt.fast_trap_idx = 0;
                 else
-                    op.u.getdomaininfo.ctxt.fast_trap_idx = 
+                    op->u.getdomaininfo.ctxt.fast_trap_idx = 
                         p->thread.fast_trap_idx;
-                op.u.getdomaininfo.ctxt.ldt_base = p->mm.ldt_base;
-                op.u.getdomaininfo.ctxt.ldt_ents = p->mm.ldt_ents;
-                op.u.getdomaininfo.ctxt.gdt_ents = 0;
+                op->u.getdomaininfo.ctxt.ldt_base = p->mm.ldt_base;
+                op->u.getdomaininfo.ctxt.ldt_ents = p->mm.ldt_ents;
+                op->u.getdomaininfo.ctxt.gdt_ents = 0;
                 if ( GET_GDT_ADDRESS(p) == GDT_VIRT_START )
                 {
                     for ( i = 0; i < 16; i++ )
-                        op.u.getdomaininfo.ctxt.gdt_frames[i] = 
+                        op->u.getdomaininfo.ctxt.gdt_frames[i] = 
                             l1_pgentry_to_pagenr(p->mm.perdomain_pt[i]);
-                    op.u.getdomaininfo.ctxt.gdt_ents = 
+                    op->u.getdomaininfo.ctxt.gdt_ents = 
                         (GET_GDT_ENTRIES(p) + 1) >> 3;
                 }
-                op.u.getdomaininfo.ctxt.ring1_ss  = p->thread.ss1;
-                op.u.getdomaininfo.ctxt.ring1_esp = p->thread.esp1;
-                op.u.getdomaininfo.ctxt.pt_base   = 
+                op->u.getdomaininfo.ctxt.ring1_ss  = p->thread.ss1;
+                op->u.getdomaininfo.ctxt.ring1_esp = p->thread.esp1;
+                op->u.getdomaininfo.ctxt.pt_base   = 
                     pagetable_val(p->mm.pagetable);
-                memcpy(op.u.getdomaininfo.ctxt.debugreg, 
+                memcpy(op->u.getdomaininfo.ctxt.debugreg, 
                        p->thread.debugreg, 
                        sizeof(p->thread.debugreg));
-                op.u.getdomaininfo.ctxt.event_callback_cs  = p->event_selector;
-                op.u.getdomaininfo.ctxt.event_callback_eip = p->event_address;
-                op.u.getdomaininfo.ctxt.failsafe_callback_cs  = 
+                op->u.getdomaininfo.ctxt.event_callback_cs  =
+                    p->event_selector;
+                op->u.getdomaininfo.ctxt.event_callback_eip =
+                    p->event_address;
+                op->u.getdomaininfo.ctxt.failsafe_callback_cs  = 
                     p->failsafe_selector;
-                op.u.getdomaininfo.ctxt.failsafe_callback_eip = 
+                op->u.getdomaininfo.ctxt.failsafe_callback_eip = 
                     p->failsafe_address;
             }
         }
         read_unlock_irqrestore(&tasklist_lock, flags);
-        copy_to_user(u_dom0_op, &op, sizeof(op));
+        copy_to_user(u_dom0_op, op, sizeof(*op));
     }
     break;
 
     case DOM0_GETPAGEFRAMEINFO:
     {
         struct pfn_info *page;
-        unsigned long pfn = op.u.getpageframeinfo.pfn;
-        unsigned int dom = op.u.getpageframeinfo.domain;
+        unsigned long pfn = op->u.getpageframeinfo.pfn;
+        unsigned int dom = op->u.getpageframeinfo.domain;
         struct task_struct *p;
 
         ret = -EINVAL;
@@ -356,17 +368,17 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         {
             ret = 0;
 
-            op.u.getpageframeinfo.type = NONE;
+            op->u.getpageframeinfo.type = NONE;
 
             if ( (page->type_and_flags & PGT_count_mask) != 0 )
             {
                 switch ( page->type_and_flags & PGT_type_mask )
                 {
                 case PGT_l1_page_table:
-                    op.u.getpageframeinfo.type = L1TAB;
+                    op->u.getpageframeinfo.type = L1TAB;
                     break;
                 case PGT_l2_page_table:
-                    op.u.getpageframeinfo.type = L2TAB;
+                    op->u.getpageframeinfo.type = L2TAB;
                     break;
                 }
             }
@@ -376,38 +388,38 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
         put_task_struct(p);
 
-        copy_to_user(u_dom0_op, &op, sizeof(op));
+        copy_to_user(u_dom0_op, op, sizeof(*op));
     }
     break;
 
     case DOM0_IOPL:
     {
         extern long do_iopl(unsigned int, unsigned int);
-        ret = do_iopl(op.u.iopl.domain, op.u.iopl.iopl);
+        ret = do_iopl(op->u.iopl.domain, op->u.iopl.iopl);
     }
     break;
 
     case DOM0_MSR:
     {
-        if ( op.u.msr.write )
+        if ( op->u.msr.write )
        {
-            msr_cpu_mask = op.u.msr.cpu_mask;
-            msr_addr = op.u.msr.msr;
-            msr_lo = op.u.msr.in1;
-            msr_hi = op.u.msr.in2;
+            msr_cpu_mask = op->u.msr.cpu_mask;
+            msr_addr = op->u.msr.msr;
+            msr_lo = op->u.msr.in1;
+            msr_hi = op->u.msr.in2;
             smp_call_function(write_msr_for, NULL, 1, 1);
             write_msr_for(NULL);
        }
         else
        {
-            msr_cpu_mask = op.u.msr.cpu_mask;
-            msr_addr = op.u.msr.msr;
+            msr_cpu_mask = op->u.msr.cpu_mask;
+            msr_addr = op->u.msr.msr;
             smp_call_function(read_msr_for, NULL, 1, 1);
             read_msr_for(NULL);
 
-            op.u.msr.out1 = msr_lo;
-            op.u.msr.out2 = msr_hi;
-            copy_to_user(u_dom0_op, &op, sizeof(op));
+            op->u.msr.out1 = msr_lo;
+            op->u.msr.out2 = msr_hi;
+            copy_to_user(u_dom0_op, op, sizeof(*op));
        }
         ret = 0;
     }
@@ -416,27 +428,28 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     case DOM0_DEBUG:
     {
         extern void pdb_do_debug(dom0_op_t *);
-        pdb_do_debug(&op);
-        copy_to_user(u_dom0_op, &op, sizeof(op));
+        pdb_do_debug(op);
+        copy_to_user(u_dom0_op, op, sizeof(*op));
         ret = 0;
     }
     break;
 
     case DOM0_SETTIME:
     {
-        do_settime(op.u.settime.secs, 
-                   op.u.settime.usecs, 
-                   op.u.settime.system_time);
+        do_settime(op->u.settime.secs, 
+                   op->u.settime.usecs, 
+                   op->u.settime.system_time);
         ret = 0;
     }
     break;
     
     case DOM0_READCONSOLE:
     {
-       extern long read_console_ring(unsigned long, unsigned int, unsigned int);
-        ret = read_console_ring(op.u.readconsole.str, 
-                               op.u.readconsole.count,
-                               op.u.readconsole.cmd); 
+       extern long read_console_ring(unsigned long, 
+                                      unsigned int, unsigned int);
+        ret = read_console_ring(op->u.readconsole.str, 
+                               op->u.readconsole.count,
+                               op->u.readconsole.cmd); 
     }
     break;    
 
@@ -445,5 +458,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     }
 
+ out:
+    kfree(op);
     return ret;
 }
index 37302850e5717bf969a27786d4c929fe6b3acddd..5bcc450b5c691ce93296c6922b15dd62729e9e9a 100644 (file)
@@ -818,7 +818,7 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
                                 (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
                                 info->nsectors_buffered);
 
-    char *dest;
+    char *dest, *dum;
 
     /* If we couldn't get a buffer, don't try to buffer anything... */
     if (info->buffer == NULL)
@@ -839,11 +839,12 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
     }
 
     /* Throw away any remaining data. */
+    dum = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
     while (sectors_to_transfer > 0) {
-       char dum[SECTOR_SIZE];
-       atapi_input_bytes (drive, dum, sizeof (dum));
+       atapi_input_bytes (drive, dum, SECTOR_SIZE);
        --sectors_to_transfer;
     }
+    kfree(dum);
 }
 
 /*
@@ -896,6 +897,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
     struct cdrom_info *info = drive->driver_data;
     int i, dma = info->dma, dma_error = 0;
     ide_startstop_t startstop;
+    char *dum;
 
     struct request *rq = HWGROUP(drive)->rq;
 
@@ -965,15 +967,20 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
     nskip = MIN ((int)(rq->current_nr_sectors - (rq->bh->b_size >> SECTOR_BITS)),
                 sectors_to_transfer);
 
+    if ( (dum = kmalloc(SECTOR_SIZE, GFP_ATOMIC)) == NULL )
+    {
+       cdrom_end_request (0, drive);
+       return ide_stopped;        
+    }
     while (nskip > 0) {
        /* We need to throw away a sector. */
-       char dum[SECTOR_SIZE];
-       atapi_input_bytes (drive, dum, sizeof (dum));
+       atapi_input_bytes (drive, dum, SECTOR_SIZE);
 
        --rq->current_nr_sectors;
        --nskip;
        --sectors_to_transfer;
     }
+    kfree(dum);
 
     /* Now loop while we still have data to read from the drive. */
     while (sectors_to_transfer > 0) {
index 6dc740405ddcd08e3d8b7c39e0bb7a098aac4bc1..530e4ce238b6afcbb4208af3ade6b6628893b28c 100644 (file)
 
 #define capable(_c) 0
 
+#define STACK_GUARD
 #ifndef NDEBUG
 #define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
                            __FILE__, __LINE__, ## _a)
-#define STACK_GUARD
 #else
 #define DPRINTK(_f, _a...) ((void)0)
 #endif